from homeassistant.config_entries import ConfigFlow, OptionsFlow, ConfigEntry
from .const import CONF_SELECT, DOMAIN,AUTH_URL
import random
import homeassistant.helpers.config_validation as cv
import voluptuous as vol
import logging
import json
import aiohttp            

_LOGGER = logging.getLogger(__name__)
from .const import DEV_LIST
ACTIONS = {
    'cloud': "Add Mi Cloud Account",
    'token': "Add Gateway using Token"
}

def getRandChar(length):
    _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"
    return ''.join(random.sample(_chars, length))
    
class ExampleConfigFlow(ConfigFlow, domain=DOMAIN):
    VERSION = 1
    @staticmethod
    def async_get_options_flow(config_entry):
        """Get the options flow for this handler."""
        return optionsFlowHandler(config_entry)

    async def async_step_user(self, user_input=None,error=None):
        if user_input is not None:
            self._config = user_input
            data = {'username': user_input['username'], 'password': user_input['password']}
            url = AUTH_URL
            
            async with aiohttp.ClientSession() as session:
                async with session.post(url,data=data) as res:
                    if res.status != 200:
                        if res.status == 401:
                            return await self.async_step_user(error='value_error')
                        if res.status == 429:
                            return await self.async_step_user(error='unexpected_error')
                        
            return await self.async_step_seldomain()

        return self.async_show_form(
            step_id='user',
            data_schema=vol.Schema({
                vol.Required("username"): str,
                vol.Required("password"): str,
            }),
            errors={'base': error} if error else None
        )

    async def async_step_seldomain(self, user_input=None):
        if user_input is not None:
            self._config['domain'] = user_input['domain']
            return await self.async_step_seldevices(user_input)
        return self.async_show_form(
            step_id = 'seldomain',
            data_schema = vol.Schema({
                vol.Required('domain',default=DEV_LIST):cv.multi_select(DEV_LIST)
            })
        )
    async def async_step_seldevices(self, user_input=None):
        if 'domain' in user_input:
            states = self.hass.states.async_all()
            #devices = []
            devices = [
                state.entity_id+'/'+state.attributes['friendly_name'] 
                for state in states 
                if state.domain in user_input['domain'] and 'friendly_name' in state.attributes
            ]
            #for state in states:
            #    if state.domain in user_input['domain']:
            #        if hasattr(state.attributes,'friendly_name'):
            #            devices.append(state.entity_id+"/"+state.attributes['friendly_name'])  
            return self.async_show_form(
                step_id = 'seldevices',
                data_schema = vol.Schema({
                    vol.Required('devices',default=devices):cv.multi_select(devices)
                })
            )
        else:
            self._config['devices'] = user_input['devices']
            self._config['uid'] = getRandChar(16)
            
            return self.async_create_entry(title=self._config['username'],data=self._config)
            

class optionsFlowHandler(OptionsFlow):
    def __init__(self, config_entry):
        """Initialize MQTT options flow."""
        self.config_entry = config_entry
        self._config = {}
        for k in config_entry.data:
            self._config[k] = config_entry.data[k]

    async def async_step_init(self, user_input=None,errors=None):
        domains = self._config['domain']
        if user_input is not None:
            self._config['domain'] = user_input['domain']
            self._config['devices'] = [
                    dev for dev  in self._config['devices'] 
                    if dev.split('/')[0].split('.')[0] in self._config['domain']
                ]
            return await self.async_step_select_device()
            #return self.async_create_entry(title="", data=user_input)

        return self.async_show_form(
            step_id = 'init',
            data_schema = vol.Schema({
                vol.Required('domain',default=domains):cv.multi_select(DEV_LIST)
            }),
            last_step=False,
        )
        
    async def async_step_select_device(self,user_input=None,errors=None):
        if user_input is not None:
            self._config['devices'] = user_input['devices']
            self.hass.config_entries.async_update_entry(
                    self.config_entry, data=self._config
                )
            return self.async_create_entry(title="", data=None)
        
        states = self.hass.states.async_all()
        states = [
            state.entity_id+'/'+state.attributes['friendly_name'] 
            for state in states 
            if state.domain in self._config['domain']
        ]
        return self.async_show_form(
            step_id="select_device",
            data_schema=vol.Schema({
                    vol.Required(
                        'devices',default=self._config['devices']
                    ):cv.multi_select(states)
                }),
            errors=errors,
            last_step=False,
        )